/* eslint-disable react/no-danger */
/* eslint-disable @typescript-eslint/no-unused-vars */
import React, { useRef } from 'react';
import { Collapse } from 'antd';
import hljs from 'highlight.js';
import MarkdownIt from 'markdown-it';
import hooks1 from '@/assets/images/advanceReact/hooks1.png';
import updateStateUrl from '@/assets/images/advanceReact/update_state.png';

import 'highlight.js/styles/atom-one-light.css';
import './index.less';

const { Panel } = Collapse;
const mdParser = MarkdownIt({
  html: true,
  linkify: true,
  typographer: true,
  highlight(str, lang) {
    if (lang && hljs.getLanguage(lang)) {
      try {
        return hljs.highlight(lang, str).value;
      } catch (error) {
        console.log(error);
      }
    }
    return ''; // 使用额外的默认转义
  },
});

export default function Hooks() {
  const exampleCode =
    '```js' +
    `
    let isMounted = false;
    function Example() {
      console.log('isMounted', isMounted);
      if(!isMounted) {
        const [name, setName] = useState('bob');
        const [age] = useState('28');

        isMounted = true;
      }
      const [career, setCareer] = useState('前端');
      // 点击按钮后，此处会打印career tom
      console.log('career',career);
      return (
        <div>
          <p>姓名：{name}</p>
          <p>年龄：{age}</p>
          <p>职业：{career}</p>

          <button type="button" onClick={() => setName('tom')}>修改名字</button>
        </div>
      )
    }
  `;

  const sourceCode1 =
    '```js' +
    `
    function mountState(initalState) {
      // 将新的hook对象追加进链表尾部
      var hook = mountWorkInProgressHook();

      // initialState可以是一个回调
      if(typeof initialState === 'function') {
        initialState = initialState();
      }

      // 创建当前hook对象的更新队列，这一步主要是为了能够依序保留dispatch
      const queue = hook.queue = {
        last: null,
        dispatch: null,
        lastRenderedReducer: basicStateReducer,
        lastRenderedState: (initialState: any)
      };

      // 将initialState作为一个"记忆值"存下来
      hook.memoizedState = hook.baseState = initialState;

      // dispatch是由上下文一个叫disptachAction的方法创建的，这里不必纠结这个方法做了什么
      var dispath = queue.dispath =
        dispatchAction.bind(null, currentlyRenderingFiber$1, queue);

      // 返回目标数组，dispatch其实就是实例中的setXXX这个函数
      return [hook.memoizedState, dispatch];
    }
`;

  const sourceCode2 =
    '```js' +
    `
    function mountWorkInProgressHook() {
      var hook = {
        memoizedState: null,
        baseState: null,
        baseQueue: null,
        queue: null,
        next: null,
      }

      if(workInProgressHook === null) {
        // 这行代码每个React版本都不太一样，但归根结底都是为了将hook作为链表的头节点处理
        firstWorkInProgressHook = workInProgressHook = hook;
      } else {
        // 若链表不为空，则将hook追加到链表尾部
        workInProgressHook = workInProgressHook.next = hook;
      }

      return workInProgressHook;
    }
    `;
  return (
    <div className="advance-react-wrapper">
      <Collapse defaultActiveKey={['1', '2', '3']}>
        <Panel header="1、函数组件与类组件的区别" key="1">
          <ul>
            <li>类组件需要继承class,函数组件不需要</li>
            <li>类组件可以访问生命周期方法，函数组件不能</li>
            <li>
              类组件中可以获取到实例化后的this,并基于这个this做各种各样的事情，而函数组件不可以
            </li>
            <li>类组件中可以定义并维护state (状态)，而函数组件不可以</li>
          </ul>
          <p>
            &emsp;hooks出现前，类组件的能力边界上显然高于函数组件，两类组件最大的不同在于函数组件会捕获render内部的状态，每一次渲染得到的都是独立的作用域，不会影响先前的逻辑。
          </p>
        </Panel>
        <Panel header="2、Hooks的本质: 一套能够使函数组件更强大、更灵活的“钩子”" key="2">
          <ul>
            <li>useState: 为函数组件引入状态</li>
            <li>useEffect: 为函数组件引入生命周期，允许执行副作用操作</li>
          </ul>
        </Panel>
        <Panel header="3、为什么需要React-Hooks" key="3">
          <ul>
            <li>告别难以理解的Class(this、生命周期)</li>
            <li>解决业务逻辑难以拆分问题</li>
            <li>使状态逻辑复用变得简单可行</li>
            <li>函数组件从设计思想上来看更加契合React的理想，UI=render(data)</li>
          </ul>
        </Panel>
        <Panel header="4、Hooks并非万能" key="4">
          <ul>
            <li>getSnapshotBeforeUpdate、componentWillCatch无法代替</li>
            <li>
              更加严格的约束
              <Collapse>
                <Panel header="1、只在react函数中调用hooks" key="1" />
                <Panel
                  header="2、不要在循环、条件或嵌套函数中调用hooks，为了就是保证hooks每次渲染都保持同样的执行顺序"
                  key="2"
                >
                  <p>
                    <h4>示例：</h4>
                    <div
                      style={{ width: '70%' }}
                      className="code-wrapper"
                      dangerouslySetInnerHTML={{
                        __html: mdParser.render(exampleCode),
                      }}
                    />
                    <h4>相关源码：</h4>
                    <div>
                      挂载：
                      <img src={hooks1} alt="" width="50%" />
                      <div style={{ display: 'flex', gap: 20, marginTop: 20 }}>
                        <div
                          style={{ width: '50%' }}
                          className="code-wrapper"
                          dangerouslySetInnerHTML={{
                            __html: mdParser.render(sourceCode1),
                          }}
                        />
                        <div
                          style={{ width: '50%' }}
                          className="code-wrapper"
                          dangerouslySetInnerHTML={{
                            __html: mdParser.render(sourceCode2),
                          }}
                        />
                      </div>
                    </div>
                    <div>
                      更新：
                      <img src={updateStateUrl} alt="" width="50%" />
                    </div>
                  </p>
                </Panel>
              </Collapse>
            </li>
          </ul>
        </Panel>
      </Collapse>
    </div>
  );
}
